#pragma once

#include "nfa.h"
#include <map>

namespace regex
{

class Dfa
{
public:
    uint get_start_state() const;
    bool get_next_state(uint curr, const Input &input, uint &next) const;
    bool is_accept(uint u) const;

    void add_transition(uint curr, uint next, const std::string &trigger);
    void set_accept(uint curr);
};

class DfaMatcher
{
public:
    static bool match(const Dfa &dfa, const std::string &str, MatchResult &mr); 
};

class DfaBuilder
{
public:
    static bool build(const Nfa &nfa, Dfa &dfa);  

private:
    template<class T>
    static void unique(T &states);
    static uint get_next_dfa_state(const std::vector<uint> &states);

private:
    static std::map<std::string, uint> s_states_map;
    static uint DfaBuilder::s_dfa_curr;
};

template<class T>
void DfaBuilder::unique(T &states)
{
    std::sort(states.begin(), states.end());
    for (size_t i = states.size(); i > 1; --i)
    {
        if (states[i - 1] == states[i - 2])
        {
            states.erase(states.begin() + i - 1);
        }
    }
}

}
